package com.zz.yt.lib.ui.refresh;


import android.annotation.SuppressLint;

import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import com.blankj.utilcode.util.JsonUtils;
import com.blankj.utilcode.util.ObjectUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter;
import com.chad.library.adapter.base.listener.OnItemClickListener;
import com.chad.library.adapter.base.listener.OnLoadMoreListener;
import com.flyco.tablayout.listener.OnTabSelectListener;
import com.whf.android.jar.app.Latte;
import com.whf.android.jar.base.delegate.BaseDelegate;
import com.whf.android.jar.constants.HttpConstant;
import com.whf.android.jar.net.HttpCode;
import com.whf.android.jar.net.RestClient;
import com.whf.android.jar.net.callback.IError;
import com.whf.android.jar.net.callback.IFailure;
import com.whf.android.jar.net.callback.ISuccess;
import com.whf.android.jar.util.log.LatteLogger;
import com.youth.banner.listener.OnBannerListener;
import com.zz.yt.lib.ui.R;
import com.zz.yt.lib.ui.base.LatteDelegate;
import com.zz.yt.lib.ui.listener.OnClickBannerListener;
import com.zz.yt.lib.ui.listener.OnClickBoolListener;
import com.zz.yt.lib.ui.listener.OnClickChoiceListener;
import com.whf.android.jar.popup.listener.OnClickDecisionListener;
import com.zz.yt.lib.ui.listener.OnClickIntBoolListener;
import com.zz.yt.lib.ui.listener.OnClickIntCheckListener;
import com.zz.yt.lib.ui.listener.OnClickIntListener;
import com.zz.yt.lib.ui.listener.OnClickIntObjListener;
import com.zz.yt.lib.ui.listener.OnClickIntStrListener;
import com.zz.yt.lib.ui.listener.OnClickObjectListener;
import com.zz.yt.lib.ui.listener.OnClickStrObjListener;
import com.zz.yt.lib.ui.listener.OnClickStringListener;
import com.zz.yt.lib.ui.listener.OnClickTableListener;
import com.zz.yt.lib.ui.recycler.adapter.MultipleRecyclerAdapter;
import com.zz.yt.lib.ui.recycler.data.BaseDataConverter;
import com.zz.yt.lib.ui.recycler.data.MultipleItemEntity;
import com.zz.yt.lib.ui.recycler.holder.MultipleViewHolder;
import com.zz.yt.lib.ui.utils.ObjUtils;

import java.util.List;
import java.util.WeakHashMap;


/**
 * 分页数据和刷新处理
 *
 * @author qf
 * @version 1.0
 */
public abstract class BaseRefreshHandler implements IClickListener, IFailure, IError,
        OnLoadMoreListener, SwipeRefreshLayout.OnRefreshListener {

    protected final LatteDelegate DELEGATE;
    protected final SwipeRefreshLayout REFRESH_LAYOUT;
    protected final PagingBean BEAN;
    protected final RecyclerView RECYCLERVIEW;
    protected final BaseDataConverter CONVERTER;

    private String mUrl = null;
    private final WeakHashMap<String, Object> PARAMS = new WeakHashMap<>();

    private OnTabSelectListener mTabSelectListener = null;
    private OnItemClickListener mItemClickListener = null;
    private OnClickIntListener mClickIntListener = null;
    private OnClickIntBoolListener mClickIntBoolListener = null;
    private OnClickIntObjListener mClickIntObjListener = null;
    private OnClickIntStrListener mClickIntStrListener = null;
    private OnClickStringListener mClickStringListener = null;
    private OnClickStrObjListener mClickStrObjListener = null;
    private OnClickObjectListener mClickObjectListener = null;
    private OnClickTableListener mClickTableListener = null;
    protected OnClickBoolListener mClickBoolListener = null;
    protected OnClickBannerListener mBannerListener = null;
    protected OnClickChoiceListener mClickChoiceListener = null;
    protected OnClickIntCheckListener mClickIntCheckListener = null;
    protected OnClickDecisionListener mClickDecisionListener = null;

    protected BaseRefreshHandler(LatteDelegate delegate,
                                 SwipeRefreshLayout swipeRefreshLayout,
                                 RecyclerView recyclerView,
                                 BaseDataConverter converter) {
        this.DELEGATE = delegate;
        this.REFRESH_LAYOUT = swipeRefreshLayout;
        this.REFRESH_LAYOUT.setOnRefreshListener(this);
        this.RECYCLERVIEW = recyclerView;
        this.CONVERTER = converter;
        this.BEAN = new PagingBean();
    }

    /**
     * 初始化事件
     */
    protected void setListener(MultipleRecyclerAdapter adapter) {
        if (adapter != null) {
            try {
                adapter.setEmptyView(R.layout.hai_loading_view);
            } catch (Exception e) {
                LatteLogger.e(e.getMessage());
            }
            adapter.setOnBannerListener(new OnBannerListener() {
                @Override
                public void OnBannerClick(int position) {
                    if (mBannerListener != null) {
                        mBannerListener.OnBannerClick(position);
                    }
                }
            });
            if (mTabSelectListener != null) {
                adapter.setOnTabSelectListener(mTabSelectListener);
            }
            if (mItemClickListener != null) {
                adapter.setOnItemClickListener(mItemClickListener);
            }
            if (mClickIntListener != null) {
                adapter.setOnClickIntListener(mClickIntListener);
            }
            if (mClickIntBoolListener != null) {
                adapter.setOnClickIntBoolListener(mClickIntBoolListener);
            }
            if (mClickIntObjListener != null) {
                adapter.setOnClickIntObjListener(mClickIntObjListener);
            }
            if (mClickIntStrListener != null) {
                adapter.setOnClickIntStrListener(mClickIntStrListener);
            }
            if (mClickStringListener != null) {
                adapter.setOnClickStringListener(mClickStringListener);
            }
            if (mClickStrObjListener != null) {
                adapter.setOnClickStrObjListener(mClickStrObjListener);
            }
            if (mClickObjectListener != null) {
                adapter.setOnClickObjectListener(mClickObjectListener);
            }
            if (mClickTableListener != null) {
                adapter.setOnClickTableListener(mClickTableListener);
            }
            if (mClickDecisionListener != null) {
                adapter.setOnClickDecisionListener(mClickDecisionListener);
            }
        }
    }

    /***
     * 列表数据查询
     * @param url：
     */
    public void firstPage(String url) {
        firstPage(url, null);
    }

    /***
     * 列表数据查询：
     * @param url：
     * @param params：
     */
    public void firstPage(String url, WeakHashMap<String, Object> params) {
        mUrl = url;
        // 清空之前的搜索条件
        PARAMS.clear();
        // 搜索、分页的条件。
        if (params != null) {
            //防止空指针异常，这次是清空在添加，不直接替换。
            PARAMS.putAll(params);
        }
        // 下拉刷新事件
        REFRESH_LAYOUT.setRefreshing(true);
        // 需要重置页数
        BEAN.reset();
        refresh(mUrl, PARAMS, true);
    }

    /**
     * 判断是否有下一页或当前页是否足条
     */
    private void paging() {
        final int pageSize = BEAN.getPageSize();
        final int currentCount = BEAN.getCurrentCount();
        final int total = BEAN.getTotal();
        final int size = getData() == null ? 0 : getData().size();
        if (size < pageSize || currentCount >= total) {
            if (getAdapter() != null) {
                getAdapter().getLoadMoreModule().loadMoreEnd(false);
            }
        } else {
            refresh(mUrl, PARAMS, false);
        }
    }

    @Override
    public void onRefresh() {
        // 这里的作用是防止下拉刷新的时候还可以上拉加载
        if (getAdapter() != null) {
            getAdapter().getLoadMoreModule().setEnableLoadMore(false);
        }
        // 下拉刷新事件
        REFRESH_LAYOUT.setRefreshing(true);
        // 需要重置页数
        BEAN.reset();
        refresh(mUrl, PARAMS, true);
    }

    /***
     * 下一页
     * @param data:
     */
    protected void setPaging(String data, MultipleRecyclerAdapter adapter) {
        if (adapter != null) {
            BEAN.setTotal(JsonUtils.getInt(data, HttpConstant.TOTAL))
                    .setCurrentCount(adapter.getData().size())
                    .addIndex();
            try {
                adapter.getLoadMoreModule().loadMoreComplete();
            } catch (Exception e) {
                LatteLogger.e(e.getMessage());
            }
        }
    }

    @Override
    public void onLoadMore() {
        paging();
    }

    /***************************************** set refresh ******************************************/

    protected abstract void onSuccess(String data, boolean refresh);

    /**
     * 模拟网络请求
     */
    protected void inNoNet() {
        Latte.getHandler().postDelayed(new Runnable() {
            @Override
            public void run() {
                //仿网络请求
                REFRESH_LAYOUT.setRefreshing(false);
                onSuccess("", true);
            }
        }, 600);
    }


    /***
     * 刷新：
     * @param url：
     * @param params：
     * @param refresh：
     */
    protected void refresh(String url, WeakHashMap<String, Object> params, final boolean refresh) {
        if (ObjectUtils.isEmpty(url)) {
            inNoNet();
            return;
        }
        params();
        RestClient.builder()
                .url(url)
                .params(params)
                .success(new ISuccess() {
                    @Override
                    public void onSuccess(String response) {
                        code(response, refresh);
                    }
                })
                .error(this)
                .failure(this)
                .build()
                .get();
    }

    /**
     * @param response:默认返回处理
     * @param refresh：返回的data
     */
    @SuppressLint("WrongConstant")
    protected void code(String response, boolean refresh) {
        REFRESH_LAYOUT.setRefreshing(false);
        if (ObjectUtils.isEmpty(response)) {
            return;
        }
        LatteLogger.json(response);
        final int code = ObjUtils.getCode(response);
        if (HttpCode.CODE_0 == code || HttpCode.CODE_200 == code) {
            final String data = ObjUtils.getData(response);
            onSuccess(data, refresh);
        } else {
            onError(code, Latte.getMessage(response));
        }
    }

    /***
     * getAdapter
     * @return adapter
     */
    public abstract BaseMultiItemQuickAdapter<MultipleItemEntity, MultipleViewHolder> getAdapter();

    /***
     * getData
     * @return list
     */
    public abstract List<MultipleItemEntity> getData();


    /***************************************** set page ******************************************/

    @Override
    public WeakHashMap<String, Object> params() {
        return params("pageNumber", "pageSize");
    }

    @Override
    public WeakHashMap<String, Object> params(String keyNumber, String keySize) {
        PARAMS.put(keyNumber, BEAN.getPageIndex());
        PARAMS.put(keySize, BEAN.getPageSize());
        return PARAMS;
    }

    /************************************** Set Listener *****************************************/

    @Override
    public void setOnBannerListener(OnClickBannerListener listener) {
        this.mBannerListener = listener;
    }

    @Override
    public void setOnTabSelectListener(OnTabSelectListener listener) {
        this.mTabSelectListener = listener;
    }

    @Override
    public void setOnItemClickListener(OnItemClickListener listener) {
        this.mItemClickListener = listener;
    }

    @Override
    public void setOnClickIntListener(OnClickIntListener listener) {
        this.mClickIntListener = listener;
    }

    @Override
    public void setOnClickIntBoolListener(OnClickIntBoolListener listener) {
        this.mClickIntBoolListener = listener;
    }

    @Override
    public void setOnClickIntObjListener(OnClickIntObjListener listener) {
        this.mClickIntObjListener = listener;
    }

    @Override
    public void setOnClickIntStrListener(OnClickIntStrListener listener) {
        this.mClickIntStrListener = listener;
    }

    @Override
    public void setOnClickBoolListener(OnClickBoolListener listener) {
        this.mClickBoolListener = listener;
    }

    @Override
    public void setOnClickChoiceListener(OnClickChoiceListener listener) {
        this.mClickChoiceListener = listener;
    }

    @Override
    public void setOnClickObjectListener(OnClickObjectListener listener) {
        this.mClickObjectListener = listener;
    }

    @Override
    public void setOnClickStringListener(OnClickStringListener listener) {
        this.mClickStringListener = listener;
    }

    @Override
    public void setOnClickStrObjListener(OnClickStrObjListener listener) {
        this.mClickStrObjListener = listener;
    }

    @Override
    public void setOnClickTableListener(OnClickTableListener listener) {
        this.mClickTableListener = listener;
    }

    @Override
    public void setOnClickIntCheckListener(OnClickIntCheckListener listener) {
        this.mClickIntCheckListener = listener;
    }

    @Override
    public void setOnClickDecisionListener(OnClickDecisionListener listener) {
        this.mClickDecisionListener = listener;
    }

    @Override
    public void onFailure() {
        REFRESH_LAYOUT.setRefreshing(false);
        if (DELEGATE != null) {
            DELEGATE.onFailure();
        } else {
            ToastUtils.showShort("服务器连接失败，请稍后重试。");
        }
    }

    @Override
    public void onError(int code, String msg) {
        REFRESH_LAYOUT.setRefreshing(false);
        if (DELEGATE != null) {
            DELEGATE.onError(code, msg);
        } else {
            if (HttpCode.CODE_404 == code) {
                ToastUtils.showShort("服务器找不到请求的接口");
            } else {
                //对服务连接异常处理。
                ToastUtils.showShort(ObjectUtils.isEmpty(msg) ? "服务器异常，请联系管理员" : msg);
            }
        }
    }

    /**
     * @param delegate:跳转
     */
    protected void start(BaseDelegate delegate) {
        if (DELEGATE == null) {
            LatteLogger.e("DELEGATE is null,no out Delegate");
            return;
        }
        if (DELEGATE != null) {
            DELEGATE.start(delegate);
        }
    }

    /**
     * @param delegate:跳转
     */
    protected void startForResult(BaseDelegate delegate, int requestCode) {
        if (DELEGATE == null) {
            LatteLogger.e("DELEGATE is null,no out Delegate");
            return;
        }
        if (DELEGATE != null) {
            DELEGATE.startForResult(delegate, requestCode);
        }
    }

}

